package com.siteseat.crudeq.kernel.impl;

import java.io.IOException;

import com.siteseat.common.exception.InternalException;
import com.siteseat.common.foundation.Component;
import com.siteseat.common.foundation.PropertyHelper;
import com.siteseat.crudeq.kernel.ChunkManager;
import com.siteseat.crudeq.kernel.Message;
import com.siteseat.crudeq.kernel.MessageHistory;
import com.siteseat.crudeq.kernel.MessageId;
import com.siteseat.crudeq.kernel.Queue;
import com.siteseat.crudeq.kernel.QueueListener;
import com.siteseat.crudeq.kernel.QueueProfile;
import com.siteseat.crudeq.kernel.exception.InvalidChunkException;

/**
 *
 */
public class QueueImpl extends Component implements Queue {

  private QueueProfile          profile;

  private ChunkManager     chunkManager;

  private QueueListener    listener;

  private volatile boolean enabled;

  /**
   * @param profile
   * @param chunkManager
   */
  public QueueImpl( QueueProfile profile, ChunkManager chunkManager ) {
    this.profile = profile;
    this.chunkManager = chunkManager;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void ensureEnabled() {
    if( isEnabled() == false ) {
      throw new InternalException( "Not enabled" );
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isEnabled() {
    return enabled && isInited();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setEnabled( boolean enabled ) {
    this.enabled = enabled;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long getFirstChunkId() {
    return chunkManager.getFirstChunkId();
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected void doInit() throws Exception {
    // super.doInit();

    PropertyHelper.ensureInitialized( log, getProfile(), "profile" );
    PropertyHelper.ensureInitialized( log, getChunkManager(), "chunkManager" );

    setEnabled( profile.isEnable() );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected void doDestroy() throws Exception {
    setEnabled( false );

    getChunkManager().destroy();

    getProfile().destroy();
  }

  /**
   * Gets the pool
   * 
   * @return the pool
   */
  public ChunkManager getChunkManager() {
    return chunkManager;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public QueueProfile getProfile() {
    return profile;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public MessageHistory history( MessageId msgId ) throws InvalidChunkException {
    ensureEnabled();

    MessageHistory r = this.chunkManager.history( msgId );
    msgId.setQueue( this );
    return r;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public QueueListener getListener() {
    return listener;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setListener( QueueListener listener ) {
    this.listener = listener;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void commit( Message msg ) {
    ensureEnabled();

    msg.commit();

    if( this.listener != null ) {
      this.listener.onMessageCommited( msg );
    }
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void rollback( Message msg ) {
    ensureEnabled();

    msg.rollback();

    /*if( this.listener != null ) {
      this.listener.onMessageRollbacked( this, msg );
    }*/
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Message prepare( int messageSize ) throws InterruptedException, IOException {
    ensureEnabled();
    return getChunkManager().prepareMessage( messageSize );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public void setBeanName( String beanName ) {
    super.setBeanName( beanName + "*" + getProfile().getId() );
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public String toString() {
    return getProfile().toString();
  }

}